/* components */
import { BaseSelectUserSelectContent, BaseSelectUserFooter } from '@src/component/common/BaseSelectUser/components'
/* enum */
import { BaseSelectUserComponentNameEnum, SelectUserComponentUser, SelectUserComponentDepartment } from '@src/component/common/BaseSelectUser/model'
/* hooks */
import { useBaseSelectUser, useBaseSelectUserOptions, useSelectUserCheckedItemList } from '@src/component/common/BaseSelectUser/hooks'
/* model */
import { BaseSelectUserPropsOptions } from '@src/component/common/BaseSelectUser/model'
/* scss */
import '@src/component/common/BaseSelectUser/index.scss'
/* vue */
import { 
  ComponentInstance, 
  // @ts-ignore
  ComponentRenderProxy, 
  ComputedRef, 
  defineComponent, 
  onBeforeMount, 
  PropType, 
  provide, 
  Ref, 
  ref 
} from 'vue'
import { CommonComponentInstance } from '@model/VC'
import { CreateElement } from 'vue'
/* store */
import store, { useBaseSelectUserStoreLoadingMap, useBaseSelectUserStoreOptions } from '@src/component/common/BaseSelectUser/store'
/* types */
import { BaseSelectUserMark } from '@src/component/common/BaseSelectUser/types'
/* util */
import { checkCompletionUserListData } from '@src/component/common/BaseSelectUser/util'
import Log from '@src/util/log'
import { isFalsy } from '@src/util/type'

export type BaseSelectUserProps = {
  options: BaseSelectUserPropsOptions;
}

export interface BaseSelectUserSetupState {
  // 是否多选状态
  isMulti: ComputedRef<boolean>;
  // 选择人员选项卡标签列表
  markList: ComputedRef<BaseSelectUserMark[]>;
  // 部门列表
  departmentList: ComputedRef<SelectUserComponentDepartment>;
  // 搜索关键字
  keyword: Ref<string>;
  // 是否处于搜索状态
  isSearching: ComputedRef<boolean>;
}

export enum BaseSelectUserEmitEventNameEnum {
  Single = 'single',
  Close = 'close',
  Multi = 'multi',
  Destroy = 'destroy'
}

export type BaseSelectUserInstance = ComponentInstance & BaseSelectUserSetupState
export type BaseSelectUserVM = ComponentRenderProxy<BaseSelectUserProps> & CommonComponentInstance & BaseSelectUserInstance

export default defineComponent({
  name: BaseSelectUserComponentNameEnum.BaseSelectUser,
  emits: [
    BaseSelectUserEmitEventNameEnum.Close,
    BaseSelectUserEmitEventNameEnum.Single,
    BaseSelectUserEmitEventNameEnum.Multi,
    BaseSelectUserEmitEventNameEnum.Destroy
  ],
  store,
  props: {
    options: {
      type: Object as PropType<BaseSelectUserPropsOptions>,
      default: () => ({}),
      required: true
    },
    onSingle: {
      type: Function
    },
    onMulti: {
      type: Function
    },
    onClose: {
      type: Function
    },
    onDestroy: {
      type: Function
    }
  },
  setup(props: BaseSelectUserProps, { emit }) {
    
    const { setOptions } = useBaseSelectUserStoreOptions()
    
    setOptions(props.options)
    
    const { isMulti, markList, departmentList } = useBaseSelectUser(props.options)
    const { checkedItemList, setCheckedItemList } = useSelectUserCheckedItemList()
    const { isShowUser, asyncConfirm } = useBaseSelectUserOptions()
    
    const { tabLoading } = useBaseSelectUserStoreLoadingMap()
    
    const visible = ref(true)
    
    /** 
     * @description  关闭 base-window 窗口
    */
    const hideWindow = () => {
      visible.value = false
    }
    
    /** 
     * @description 监听单选选人事件
    */
    const onSingleChoiceUserHandler = (user: SelectUserComponentUser) => {
      hideWindow()
      emit(BaseSelectUserEmitEventNameEnum.Single, [user])
    }
    
    /** 
     * @description 提交已选择数据到 store
    */
    const commitSelectedToStore = () => {
      
      setCheckedItemList(props.options.selected)
      
      checkCompletionUserListData(props.options.selected).then(result => {
        
        if (result) {
          setCheckedItemList(result)
        }
        
      })
      
    }
    
    onBeforeMount(() => {
      commitSelectedToStore()
    })
    
    return {
      isMulti,
      isShowUser,
      
      markList,
      departmentList,
      checkedItemList,
      tabLoading,
      visible,
      asyncConfirm,
      
      hideWindow,
      onSingleChoiceUserHandler
    }
  },
  methods: {
    /** 
    * @description 获取属性列表
    */
    getAttributes() {
      return {
        on: {
          'update:show': () => {
            this.handlerClose()
          },
          // 全屏时会有位置偏差 去除位移class
          toggleFullscreen: (isFullscreen: boolean) => {
            const baseWindowDom = document.querySelector('.base-select-user-window');
            
            if(!this.options?.isBind) return;
            if(isFullscreen){
              baseWindowDom?.classList.remove('frame-fast-select');
            }else {
              baseWindowDom?.classList.add('frame-fast-select');
            }
          }
        },
        directives: [
          {
            name: 'loading',
            value: this.tabLoading
          }
        ]
      }
    },
    /** 
     * @description 获取 base-window 组件配置
    */
    getBaseWindowOptions() {
      return this.options.baseWindowOptions
    },
    /** 
     * @description 关闭事件
    */
    handlerClose() {
      this.hideWindow()
      this.$emit(BaseSelectUserEmitEventNameEnum.Close)
    },
    /** 
     * @description 销毁事件
    */
    handlerDestroy() {
      this.hideWindow()
      this.$emit(BaseSelectUserEmitEventNameEnum.Destroy)
    },
    /** 
     * @description 确定事件
    */
    async handlerConfirm() {
      
      if (isFalsy(this.asyncConfirm)) {
        this.handlerConfirmBase()
        return
      }
      
      try {
        
        const confirmed = await (this.asyncConfirm as unknown as Function)(this.checkedItemList)
        if (confirmed) {
          this.handlerConfirmBase()
        }
        
      } catch (error) {
        Log.error(error)
      }
      
    },
    handlerConfirmBase() {
      this.$emit(BaseSelectUserEmitEventNameEnum.Multi, this.checkedItemList)
      this.handlerDestroy()
    },
    /**
     * @description 关闭事件
     * -- 支持外部调用的
     */
    close() {
      this.handlerClose()
    }
  },
  render(h: CreateElement) {
    
    const attrs = this.getAttributes()
    const options = this.getBaseWindowOptions()
    const classNames = [
      'base-select-user-window',
      this.isMulti ? 'base-select-user-multi' : 'base-select-user-single',
      this.isShowUser ? 'base-select-user-show-user' : 'base-select-user-hide-user',
      this.options?.isBind &&'frame-fast-select'
    ]
    const minWidth = this.isMulti ? 880 : 700;
    // 这里如果用户拖动了窗口以保存后的宽度为准
    let width = minWidth
    try {
      const localAreaInfo = localStorage.getItem('layx-base-select-user-window')
      if(localAreaInfo) {
        const area = JSON.parse(localAreaInfo)
        if(area && area.width && area.width > minWidth) {
          width = area.width
        }
      }
    } catch (error) {
      console.log(error)
    }
    const minHeight = 550;
    
    return (
      <base-window
        class={BaseSelectUserComponentNameEnum.BaseSelectUser}
        title={this.options.title}
        sizeData={{ minWidth, minHeight, width }}
        className={classNames}
        ref="BaseSelectUserWindowComponent"
        size="medium"
        width="820px"
        show={this.visible}
        options={options}
        unique={this.options.unique}
        top={this.options.top}
        {...attrs}
      >
        
        {/* start 选人内容 */}
        <div class="base-select-user__content">
          <BaseSelectUserSelectContent
            is-multi={this.isMulti}
            onInput={this.onSingleChoiceUserHandler}
            onConfirm={this.handlerConfirm}
            {...attrs}
          />
        </div>
        {/* start 选人内容 */}
        
        {/* start 底部按钮 */}
        {/* 非多选模式下，不渲染底部按钮，点击人员即选择，然后关闭窗口 */}
        {this.isMulti && (
          <BaseSelectUserFooter 
            onClose={this.handlerClose} 
            onConfirm={this.handlerConfirm}
          />
        )}
        {/* end 底部按钮 */}
        
      </base-window>
    )
  }
})
